#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<sw/redis++/redis++.h>
#include<chrono>
#include<thread>
#include"util.hpp"

using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;


// get 和 set
void test1(sw::redis::Redis& redis)
{
    cout<<"get 和 set 的使用"<<endl;

    redis.flushall(); // 清空所有数据

    // 设置键值对
    redis.set("key1", "111");
    redis.set("key2", "222");
    redis.set("key3", "333");

    // optinal 可隐式转为bool类型 可直接在if中判定 如果是无效元素，返回false
    auto value1 = redis.get("key1");
    if(value1)
        std::cout << "value1=" << value1.value() << std::endl;

    auto value2 = redis.get("key2");
    if(value2)
        std::cout << "value2=" << value2.value() << std::endl;

    auto value3 = redis.get("key3");
    if(value3)
        std::cout << "value3=" << value3.value() << std::endl;

    // 获取并打印不存在的键
    auto value4 = redis.get("key4");
    if(value4)
        std::cout << "value4=" << value4.value() << std::endl;
}

void test2(sw::redis::Redis& redis)
{
    std::cout<< "exists "<<std::endl;
    redis.flushall();
    redis.set("key1", "111");
    auto ret1 = redis.exists("key1");
    cout<<"key1的返回值"<<ret1<<endl;

    auto ret2 = redis.exists("key2");
    cout<<"key2的返回值"<<ret2<<endl;

    auto ret3 = redis.exists({"key1","key2","key3"}); // 传一个大括号 查询多个
    cout<<ret3<<endl;
}

void test3(sw::redis::Redis& redis)
{
    redis.flushall(); // 清楚库是非常必要的
    std::cout<<"delete"<<endl;
    redis.set("key1","111");
    redis.set("key2","222");
    redis.set("key3","333");

    auto ret1 = redis.del("key1");
    cout<<ret1<<endl;

    auto ret2 = redis.del({"key2","key3"});
    cout<<ret2<<endl;
}

void test4(sw::redis::Redis& redis)
{
    cout<<"keys"<<endl;
    redis.flushall();
    redis.set("key1","111");
    redis.set("key2","222");
    redis.set("key3","333");
    redis.set("key4","444");
    redis.set("key5","555");
    redis.set("key6","666");

    // keys的第二个参数是一个“插入迭代器” 先准备好一个保存结果的容器
    // 接下来在创建一个插入迭代器指向容器的位置，就可以把keys获取到的结果放入到插入迭代器的指定位置中去了
    vector<string> result;
    auto it = std::back_insert_iterator(result);
    redis.keys("*",it);
    printContainer(result);
}

void test5(sw::redis::Redis& redis)
{
    using namespace std::chrono_literals;
    cout<<"expire and ttl"<<endl;
    redis.flushall();

    redis.set("key","111");
    redis.expire("key",std::chrono::seconds(10));

    std::this_thread::sleep_for(2s);

    auto time = redis.ttl("key"); // 还剩多长时间过期
    cout<<time<<endl;
}

void test6(sw::redis::Redis& redis)
{
    std::cout<<"type"<<endl;
    redis.flushall();

    redis.set("key","111");
    string result = redis.type("key");
    cout<<"key type:"<<result<<endl;

    redis.lpush("key2","111"); //列表
    string result2 = redis.type("key2");
    cout<<"key2 type:"<<result2<<endl;

    redis.hset("key3","aaa","111"); // 哈希
    string result3 = redis.type("key3");
    cout<<"key3 type:"<<result3<<endl;

    redis.sadd("key4","aaa");
    string result4 = redis.type("key4");
    cout<<"key4 type:"<<result4<<endl;

    redis.zadd("key5","吕布",99);
    string result5 = redis.type("key5");
    cout<<"key5 type:"<<result5<<endl;

}

int main()
{
    // 在创建redis对象时，需要在构造函数中，指定redis服务器端地址和端口。
    sw::redis::Redis redis("tcp://127.0.0.1:6379");  


    test6(redis);


    return 0;
}